


// 基于邻接表实现的图,为了简化代码的实现,我们使用列表来代替链表
// 使用hash表来实现存储邻接表,key为顶点的实力,value为该顶点的邻接顶点的列表(链表)
class GraphAdjList {
   #adjList //直接使用Map来存储链表,Map的键是顶点值,值是链表的头节点
   constructor(vertices,edges) {
    this.#adjList = new Map();
    // 添加顶点
    for(const value of vertices) {
        this.addVertex(value);
    }
    // 添加边
    for(const [i,j] of edges) {
        this.addEdge(i,j);
    }
   }

   size() { //获取顶点数量
    return this.#adjList.size;
   }

   addVertex(val) { //添加顶点
    if(this.#adjList.has(val)) {
        throw new Error('顶点已存在');
    }
    this.#adjList.set(val,[]); //添加顶点,值是一个空数组,表示该顶点的邻接顶点
   }
   remoteVertex(val) { //删除顶点
    if(!this.#adjList.has(val)) {
        throw new Error('顶点不存在');
    }
    this.#adjList.delete(val); //删除顶点,并且还需要删除被该顶点所依赖的顶点中的该顶点
    for(const key of this.#adjList.keys()) { //遍历所有的顶点,寻找依赖该顶点的顶点,并删除该顶点
        const neighbors = this.#adjList.get(key);
        const index = neighbors.indexOf(val);
        if(index !== -1) {
            neighbors.splice(index,1); //删除依赖该顶点的顶点中的该顶点
        }
    }
   }
   addEdge(val1,val2) { //添加边
    if(!this.#adjList.has(val1) || !this.#adjList.has(val2) || val1 === val2) {
        throw new Error('顶点不存在或顶点相同');
    }
    if(this.#adjList.get(val1).includes(val2)) {
        throw new Error('边已存在');
    }
    this.#adjList.get(val1).push(val2); //添加边,将val2添加到val1的邻接顶点列表中
    this.#adjList.get(val2).push(val1); //添加边,将val1添加到val2的邻接顶点列表中
   }
   remoteEdge(val1,val2) { //删除边
    if(!this.#adjList.has(val1) || !this.#adjList.has(val2) || val1 === val2) {
        throw new Error('顶点不存在或顶点相同');
    }
    if(!this.#adjList.get(val1).includes(val2)) {
        throw new Error('边不存在');
    }
    this.#adjList.get(val1).splice(this.#adjList.get(val1).indexOf(val2),1); //删除边,将val2从val1的邻接顶点列表中删除
    this.#adjList.get(val2).splice(this.#adjList.get(val2).indexOf(val1),1); //删除边,将val1从val2的邻接顶点列表中删除
   }
   print() { //打印图
    console.log('邻接表:',this.#adjList);
    console.log('--------------------------------');
   }
}


const myGraph = new GraphAdjList([0,1,2,3,4,5],[[0,1],[0,2],[1,2],[1,3],[2,4]]);
myGraph.print();